Skip to main content

Git Cheat Sheet

GQC standards❗

  • When working on shared GQC systems like MSI server or the Microcenter, make sure the Git credentials are of GQC account like hydrotrek and not tied to a person.
  • In order to track commits from these shared accounts with respect to who pushed them, we MUST incorporate our initials in the commit message as shown below. You can also refer GitHub repositories like ai3-hackathon for examples.
        # Assume the name of person committing is - Jane Doe
    git commit -a -m "JD: Commit message"
  • If we need to track files of size > 100 MB, convert the files to ZIPs and use git-lfs to track them. This will add the files in .gitattributes. We can also have specific files tracked instead of all files with that extensions.
        # Say I need to track files under /Data folder
    zip -r Data.zip /path_to_data/
    # This will track all ZIP files and not just Data.zip
    git lfs track "*.zip"

Git (Master) Commands Shortlist

  1. git clone https://github.com/repoowner/reponame.git
  2. git pull
  3. git add file1.txt file2.cs file3.java or git add *
  4. git commit -m "Message describing commit changes"
  5. git push
  6. git checkout filename.txt
  7. git reset --hard origin/master

Git (Submodules) Commands Shortlist

Git Submodules represent Git repositories that are contained within master repositories. If you’re working with the master repository, use commands from the above (Master) shortlist. If you’re working with the submodules, use this (Submodules) shortlist.

https://git-scm.com/book/en/v2/Git-Tools-Submodules

Most important of the commands will most likely be the following. Use it to update all submodules under a repository (equivalent to git pull under each one):

git submodule update --remote --merge

Fresh Clone

  1. git clone --recurse-submodules -j8 git@github.com:gqc/hydrotrek-ssc-suite.git
  2. cd hydrotrek-ssc-suite
  3. git submodule init
  4. git submodule update

More Commands

  1. To clone a master repo and all submodules: git clone --recurse-submodules -j8 https://repo.com/repo/repo.git. NOTE: the j8 parameter is an optional performance optimization that fetches up to 8 submodules at a time in parallel.
  2. Checkout master on all submodules: git submodule foreach --recursive git checkout master
    • Lately, more repositories are using main instead of master as the primary branch. To pull in main or master when appropriate, you can use the following commands checkout the master or main branch while ignoring any errors (otherwise errors will cancel the recursive checkout):
    • git submodule foreach --recursive "git checkout master || :"
    • git submodule foreach --recursive "git checkout main || :"
  3. To create a new submodule in a master repository: git submodule add https://repo.com/repo/repo.git submodule_dir_name/
  4. After cloning a master repository that contains submodules, initialize the submodules with: git submodule init
  5. Update submodules within a master repository. This is most likely necessary after pulling (Master) changes: git submodule update. To update a single submodule, you can CD into it and issue the (Master) command to pull (2).
  6. Pull changes for all submodules: git pull --recurse-submodules
  7. For now, add submodule modified files individually after you CD in. Use Master commands.
  8. For now, commit submodules individually after you CD into them. Use Master commands.
  9. Push all changes, including submodule commits using the command: git push --recurse-submodules=on-demand. To push a single submodule, you can CD into it and issue the (Master) command to push (5)
  10. To reset all submodules in a master repository, you can use the command: git submodule foreach git reset --hard. To reset a single submodule, you can CD into it and issue the (Master) command to reset (7).

Setting a Branch to Follow Upstream

Directions from: https://gist.github.com/glennblock/1974465

# NOTE: This
# complete git commands would be like this:
git remote add upstream https://github.com/some_user/some_repo
git fetch upstream
git checkout BRANCH
git reset --hard upstream/master
git push origin BRANCH --force

Merging Forks with Upstream

https://stackoverflow.com/questions/3903817/pull-new-updates-from-original-github-repository-into-forked-github-repository

These steps can also be used to merge repositories with unrelated histories

  1. git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git
  2. git fetch upstream
  3. Merge if you can.
    • git merge upstream/master LOCAL_BRANCH --allow-unrelated-histories
  4. If merge results in errors, then rebase:
    • git rebase upstream/master

Resolving Rebase Conflicts

Accept all incoming changes: https://linuxpip.org/git-accept-all-incoming-changes/

  1. Continue current rebase: git rebase --continue
  2. If conflicts, take their code over yours: git checkout --theirs .
  3. Add the modified files: git add .
  4. Repeat from step 1 until rebase is finished.

Checkout single file from upstream

https://stackoverflow.com/questions/3334475/git-how-to-update-checkout-a-single-file-from-remote-origin-master

git checkout upstream/master -- path/to/file

Private Forks of Public Repositories

GitHub does not allow creating a private fork of a public repository directly. GQC uses a workaround for projects where we need to maintain a private copy of a public upstream repository (e.g., WNTR from USEPA).

The full workaround is documented in this gist: https://gist.github.com/0xjac/85097472043b697ab57ba1b1c7530274

Initial Setup (done once when creating the private repo)

These steps are typically done by the person setting up the GQC private repository. If the private repo already exists (e.g., gqc/WNTR), skip to the next section.

  1. Create a bare clone of the public repository
  2. Create a new private repository on GitHub
  3. Mirror-push to the new private repository
  4. Remove the temporary local repository

Cloning and Setting Up for Sync

When you clone a GQC private fork of a public repository, set up the upstream remote to enable syncing with the original:

# Clone the GQC private repository
git clone git@github.com:gqc/WNTR.git
cd WNTR

# Add the upstream (original public) repository as a remote
git remote add upstream git@github.com:USEPA/WNTR.git

# IMPORTANT: Disable pushing to upstream to prevent accidental pushes
git remote set-url --push upstream DISABLE

Syncing with Upstream

When the upstream repository has new releases or updates you want to incorporate:

# Fetch changes from upstream
git fetch upstream

# Merge upstream changes into your current branch
git merge upstream/main

# Or, if you prefer rebasing
git rebase upstream/main

# Push the merged changes to GQC's private repository
git push origin main

GQC Repositories Using This Pattern

GQC RepoUpstream Repo
gqc/WNTRUSEPA/WNTR

Git Commands Explained

  1. To clone a local copy of a remote repository codebase, such as from Git Hub or Bitbucket: git clone https://github.com/repoowner/reponame.git. This will create a subdirectory with name [repo name] in which all the source code resides. To manually set the subdirectory name, use the argument -n: git clone https://github.com/repoowner/reponame.git -n differentname
  2. If you already have a local copy of a remote repository, but you want to pull down any new changes someone else has made, use the command: git pull. NOTE: This may fail if there are conflicts. We will address conflicts later.
  3. If you have made changes to your local repository and want to add them to the remote repository so that others can pull your changes, use the following sequence of commands:
    • Stage your changes for a commit by using the command: git add file1.txt file2.cs file3.java, or you can add all modified files with git add *
    • Commit the staged changes to your local repository with the command: git commit -m "Message describing commit changes"
    • Push your local commit to the remote repository with the command: git push
  4. Both pulling and pushing run the risk of failing from remote/local conflicts. If this is the case, you need to merge the changes
  5. If you try to git pull, but it won’t work because you have uncommitted changes, you can try the following resolutions. Be warned that these will overwrite any local changes you’ve made. If you need to keep your changes, it’s best to attempt a git merge, or copy your changed file and manually merge the changes later. git checkout filename.txt checks out the remote version of a file, overwriting your local copy. git reset --hard origin/master resets all local changes and sets your local repository to match the most recently pulled code from the master remote repository. This is useful if you want to just throw out all changes before doing a conflicting git pull.

Generic Git Tips

  • Always make sure you git pull on any repositories before beginning to work on them. This will help avoid any conflicts later.
  • Always make sure you git add, git commit, and git push your changes when you’re done working on a project for an extended period of time. This will help avoid any possible conflicts when you begin working on the code again later.
  • If you make a mistake in the remote repository, you can always rollback to an older version.
  • If you rollback to an older version, it’s possible you will lose access to recent changes you’ve made to your local repository.